#include "stdafx.h"
#include <ctime>
#include <random>
#include <unordered_set>
#include "heapheapheap.hpp"
#define BOOST_TEST_MAIN test
#include <boost/test/included/unit_test.hpp>


BOOST_AUTO_TEST_CASE(Add_ExtractMin_Test)
{
    srand (1);
    std::unordered_set<int> differentPriorities;
    while (differentPriorities.size() != 1000)
    {
        differentPriorities.insert(abs(rand() % 10000));
    }

	CBinomialHeap<int, int> heap;
    int minPriority = 10001;
    int minPriorityValue = 10001;
    while (!differentPriorities.empty())
    {
        int priority = *differentPriorities.begin();
        int value = rand() % 1000;
        if (priority < minPriority)
        {
            minPriority = priority;
            minPriorityValue = value;
        }
        heap.Add(value, priority);
        differentPriorities.erase(priority);
    }

	BOOST_CHECK_EQUAL(heap.ExtractMin(), minPriorityValue);
}

BOOST_AUTO_TEST_CASE(EmptyHeapExtractMin_Test)
{
    CBinomialHeap<int, int> heap;
    BOOST_CHECK_THROW(heap.ExtractMin(), logic_error);
}

BOOST_AUTO_TEST_CASE(DecreaseValue_Test)
{
    srand (1);

    std::unordered_set<int> differentPriorities;
    while (differentPriorities.size() != 1000)
    {
        differentPriorities.insert(abs(rand() % 10000));
    }

	CBinomialHeap<int, int> heap;
    while (!differentPriorities.empty())
    {
        int prio = *differentPriorities.begin();
        int val = rand() % 1000;
        heap.Add(val, prio);
        differentPriorities.erase(prio);
    }
    int priority = -2;
    int value = 10001;
    CBinomialHeap<int, int>::CHandle h = heap.Add(value, priority);
	BOOST_CHECK_EQUAL(heap.DecreasePriority(h, -1), ET_TooBigPriority);
    BOOST_CHECK_EQUAL(heap.ExtractMin(), value);
    BOOST_WARN_EQUAL(heap.DecreasePriority(h, -3), ET_RottenHandle);
    
}

